package api.util;

import api.service.ApiConvertDataService;
import m.common.model.Model;
import m.common.model.util.ModelQueryList;
import m.system.db.TransactionManager;
import m.system.exception.MException;
import m.system.util.SystemUtil;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.LockSupport;

public class ApiConvertDataSupport implements Runnable {
    private ApiConvertDataSupport(){}
    private static boolean isRun=true;
    static Thread th;
    static final List<String> keyList=new ArrayList<>();

    @Override
    public void run() {
        while (true){
            if(keyList.isEmpty()){
                TransactionManager.closeConnection();
                LockSupport.park();
                TransactionManager.initConnection();
            }
            if(!isRun) break;
            if(keyList.isEmpty()) continue;
            String key=keyList.remove(0);
            String[] arr=key.split("\\|");
            try {
                if("update".equals(arr[2])){
                    ApiConvertDataService.executeUpdateData(arr[1],arr[3]);
                }else if("delete".equals(arr[2])){
                    ApiConvertDataService.executeDeleteData(arr[1],arr[3]);
                }
            } catch (Exception e) {
                e.printStackTrace();
                SystemUtil.println("数据转换失败：",key);
            }
        }
    }
    private static boolean hasSourceTable(String name){
        return ApiConvertDataService.hasSourceTable(name);
    }
    /**
     * 添加转换
     */
    public static <T extends Model> void addModelUpdate(Class<T> clazz,String... oids){
        TransactionManager.pushCommitBackCall(()->{
            if(hasSourceTable(clazz.getName())) {
                for(String oid : oids)
                    keyList.add("model|" + clazz.getName() + "|update|" + oid);
                LockSupport.unpark(th);
            }
        });
    }
    /**
     * 添加转换
     */
    public static <T extends Model> void addModelUpdate(Class<T> clazz, ModelQueryList modelQueryList) throws MException {
        if(hasSourceTable(clazz.getName())) {
            try {
                addModelUpdate(clazz, modelQueryList.toModelList().stream().map(Model::getOid).toArray(String[]::new));
            } catch (SQLException e) {
                throw new MException(ApiConvertDataSupport.class, e.getMessage());
            }
        }
    }
    /**
     * 添加转换
     */
    public static <T extends Model> void addModelDelete(Class<T> clazz,String... oids){
        TransactionManager.pushCommitBackCall(()->{
            if(hasSourceTable(clazz.getName())) {
                for(String oid : oids)
                    keyList.add("model|" + clazz.getName() + "|delete|" + oid);
                LockSupport.unpark(th);
            }
        });
    }
    /**
     * 添加转换
     */
    public static <T extends Model> void addModelDelete(Class<T> clazz, ModelQueryList modelQueryList) throws MException {
        if(hasSourceTable(clazz.getName())) {
            try {
                addModelDelete(clazz, modelQueryList.toModelList().stream().map(Model::getOid).toArray(String[]::new));
            } catch (SQLException e) {
                throw new MException(ApiConvertDataSupport.class, e.getMessage());
            }
        }
    }
    /**
     * 添加转换
     */
    public static void addTableUpdate(String tableOid,String... oids){
        TransactionManager.pushCommitBackCall(()->{
            if(hasSourceTable(tableOid)) {
                for(String oid : oids)
                    keyList.add("table|" + tableOid + "|update|" + oid);
                LockSupport.unpark(th);
            }
        });
    }
    /**
     * 添加转换
     */
    public static void addTableDelete(String tableOid,String... oids){
        TransactionManager.pushCommitBackCall(()->{
            if(hasSourceTable(tableOid)) {
                for(String oid : oids)
                    keyList.add("table|" + tableOid + "|delete|" + oid);
                LockSupport.unpark(th);
            }
        });
    }
    /**
     * 初始化同步消息
     */
    public static void init() {
        if(null!=th) return;
        th=new Thread(new ApiConvertDataSupport());
        th.start();
    }
    public static void close(){
        isRun=false;
        LockSupport.unpark(th);
    }

}
